

#include "EZTcp.h"
#include "EZWebsocketServer.h"
#include "EZWebsocketCB.h"
#include "EZWebsocketCon.h"
#include "EZWebsocketMsg.h"
#include "client/EZConnecter.h"
#include "EZWebsocketClient.h"
#include "loop/EZTimer.h"
#include "transport/EZNoTlsTransport.h"
#include "transport/EZTlsTransport.h"

#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"libeay32.lib")
#pragma comment(lib,"ssleay32.lib")


#ifdef _DEBUG
#pragma comment(lib,"../bin/EZTcp_d.lib")
#pragma comment(lib,"libevent_d.lib")
#pragma comment(lib,"../bin/EZWebsocket_d.lib")
#else
#pragma comment(lib,"../bin/EZTcp.lib")
#pragma comment(lib,"libevent.lib")
#pragma comment(lib,"../bin/EZWebsocket.lib")
#endif
int main()
{
	auto gt = [](){
		using namespace std::chrono;
		return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
	};
	using namespace EZWebsocket;

	EZTcp::EZLoop loop;
	
	int svrcount = 0;
	int cltcount = 0;
	auto tmr = EZTcp::EZTimer::create(&loop,1000,true);


	EZTcp::EZTCPServer<EZTlsTransport> tsvr(&loop);
	tsvr.set_certificate_file("public.pem");
	tsvr.set_privateKey_file("key.pem");

	tsvr.set_connection_callback([&](const EZTcp::EZTCPConnPtr& stream){
		EZLOG_INFO;
	});

	tsvr.set_message_callback([&](const EZTcp::EZTCPConnPtr& stream,RefBuffer buf){
		//EZLOG_INFO << std::string(buf.data<char>(),buf.valid_length());
		stream->send_msg("xixi");
		svrcount++;
	});



	EZTcp::EZConnecter<EZTlsTransport> conter;
	//conter.set_verify_locations("public.pem");
	//conter.set_certificate_file("public.pem");
	//conter.set_privateKey_file("key.pem");
	//conter.set_privateKey_file("key.pem");

	conter.set_connect_callback([&](const EZTcp::EZTCPConnPtr& stream){
		if(stream->is_connected()){
			EZLOG_INFO << "connect success";
			stream->send_msg("GET / HTTP/1.1\r\nHost: www.baidu.com\r\n\r\n");
		}	
	});

	conter.set_message_callback([&](const EZTcp::EZTCPConnPtr& stream,RefBuffer buf){
		EZLOG_INFO << "connecter" << std::string(buf.data<char>(),buf.valid_length());
		std::string msg;
		msg.resize(4000);
		stream->send_msg(msg);
		cltcount++;
        stream->close();
	});

	tsvr.start(11112);
	std::thread([&](){
		loop.run();
	}).detach();

    conter.async_connect("https://www.baidu.com/", []() {
        EZLOG_ERROR << "async error";
    });
	

#if 1
	EZWebsocketServer<EZNoTlsTransport> svr(4);

	svr.set_on_open_handler([&](const EZWebsocketConPtr& con){
		EZLOG_INFO << con->uri() << " ok";
	});

	svr.set_on_message_handler([&](const EZWebsocketConPtr& con,const EZWebsocketMsg& msg){
		//EZLOG_INFO << msg.payload();

		std::string rp;
		for(int j = 0; j < 100; ++j)
			rp += "1234567890";
		auto t1 = gt();
		for (int i = 0; i < 1; ++i)
		{
			con->send_msg(EZWebsocket::OPCODE::text, "server replay:" + rp + std::to_string(i));
		}
		auto t2 = gt();
		svrcount++;
		//EZLOG_INFO << "send time cast: " << t2 - t1;
	});

	svr.set_on_close_handler([&](const EZWebsocketConPtr& con){
		EZLOG_INFO << "closed";
	});


	svr.start_accept(11111);


	EZWebsocketClient<EZNoTlsTransport> clt(&loop);
	clt.set_on_open_handler([&](const EZWebsocketConPtr& con){
		EZLOG_INFO << "EZWebsocketClient ok";
		con->send_msg(EZWebsocket::OPCODE::text, "{\"Method\":\"Login\",\"Parameters\":{\"UserName\":\"000\",\"PassWord\":\"123\"}}");
	});

	clt.set_on_message_handler([&](const EZWebsocketConPtr& con,const EZWebsocketMsg& msg){
		//EZLOG_INFO << msg.payload();

	
			auto t1 = gt();
			for(int i = 0; i < 1; ++i)		
			con->send_msg(EZWebsocket::OPCODE::text, "{\"Method\":\"QryCommodity\",\"Parameters\":{}}");
			auto t2 = gt();
			cltcount++;
			//EZLOG_INFO << "send time cast: " << t2 - t1;
	});

	clt.set_on_close_handler([&](const EZWebsocketConPtr& con){
		EZLOG_INFO << "EZWebsocketClient closed";
	});

	std::string ip1 = "127.0.0.1";
	std::string ip2 = "47.95.215.162";

    //clt.set_proxy("http://127.0.0.1:1080");
    auto okws = "wss://okexcomreal.bafang.com:10441/websocket";
    auto baws = "wss://stream.binance.com:9443/stream?streams=!miniTicker@arr@3000ms";
    //clt.start_connect(baws);
	clt.start_connect("ws://localhost:11111/wss");
#endif
    tmr->start([&](const std::error_code& e) {
        EZLOG_INFO << "echo count server: " << svrcount << ", client count: " << cltcount;
        svrcount = 0;
        cltcount = 0;
    });

	
	conter.run();

	getchar();
	return 0;
}
